home *** CD-ROM | disk | FTP | other *** search
- /*
- * MULTI-CHANNEL MEMO DISTRIBUTION FACILITY (MMDF)
- *
- *
- * Copyright (C) 1979,1980,1981 University of Delaware
- *
- * Department of Electrical Engineering
- * University of Delaware
- * Newark, Delaware 19711
- *
- * Phone: (302) 738-1163
- *
- *
- * This program module was developed as part of the University
- * of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
- *
- * Acquisition, use, and distribution of this module and its listings
- * are subject restricted to the terms of a license agreement.
- * Documents describing systems using this module must cite its source.
- *
- * The above statements must be retained with all copies of this
- * program and may not be removed without the consent of the
- * University of Delaware.
- *
- *
- * version -1 David H. Crocker March 1979
- * version 0 David H. Crocker April 1980
- * version v7 David H. Crocker May 1981
- * version 1 David H. Crocker October 1981
- *
- */
- #include "util.h"
- #include "mmdf.h"
- #include "ch.h"
- #include <pwd.h>
- #include "cnvtdate.h"
- #include "ap.h"
- #include "dm.h"
- #include "msg.h"
- #include "hdr.h"
- #include "ns.h"
-
- /* enforce management policies on message submission */
-
- /* currently, we are only concerned about author authenticity and
- * format conformance.
- *
- * Jun 82 D. Crocker add adruid, for proc/file address protection
- * Jul 82 D. Crocker add mgt_hops, checking for looping
- * fix use of From, over Sender, for return addr
- * add use of Reply-to, over From, fro return addr
- * Jul 82 A. Chang (suny) mgt_author require mbox==username
- */
-
- extern Chan **ch_tbsrch; /* complete list of channels */
- extern FILE *mq_mffp;
- extern char *ch_dflnam; /* default channel name */
-
- extern struct passwd *getpwmid ();
- extern struct ll_struct *logptr;
- extern char *index ();
- extern char *multcat();
- extern Chan *ch_nm2struct();
- extern Domain *dm_v2route();
-
- LOCFUN mgt_forward(), mgt_author(), mgt_messageid(), mst_srcinfo(),
- mgt_via(), mgt_rcv();
-
- extern long tx_msize; /* char count of message text */
-
- extern short pro_vfadr;
-
- extern int effecid,
- userid,
- adruid,
- maxhops,
- mgt_addid,
- dlv_flgs;
-
- extern char *adr_orgspec; /* original mailbox specification */
- extern char *adr_fulldmn; /* used for the delay channel */
- extern char *blt();
- extern char *compress ();
-
- extern short lnk_nadrs; /* number of addressees for message */
-
- extern char *mq_munique, /* name of the message */
- *prm_dupval (),
- *strdup (),
- *locfullmachine,
- *locmachine,
- *locfullname,
- *locname,
- *locdomain,
- nlnultrm[], /* termination break-set for ut_stdin */
- *mailid,
- *username;
-
- char *mgt_txsrc = NULL; /* some text for Source-Info: */
- char *mgt_return = NULL; /* return address */
- int mgt_gotid; /* have seen a message-id: field */
- int mgt_inalias; /* is address in alias file */
-
- short mgt_s2return = FALSE; /* get return from Sender */
-
- char mgt_dlname[] = "delay"; /* name of the delay channel */
- int mgt_nodelay = FALSE; /* don't use delay channel if true */
- int mgt_amdelay = FALSE; /* I really am the delay channel */
-
- LOCVAR struct ch_hstchan
- {
- Chan *mgt_achan; /* channel relay coming in on */
- char *mgt_ahost; /* official host name on channel */
- } mgt_vchan; /* caller is coming in from chan x */
-
- LOCVAR Chan *mgt_chdfl;
- LOCVAR short mgt_trust, /* pass on author authentication? */
- #define NRMFROM 0 /* normal checking */
- #define FLGFROM 1 /* flag as unauthenticated */
- #define OKFROM 2 /* ignore validity */
- mgt_rt2sndr, /* if a return mail message is needed */
- /* send it to submittor */
- mgt_rtgot, /* got the return address */
- mgt_remail, /* this was remailed */
- mgt_okauthor, /* an author field was acceptable */
- mgt_fmcnt, /* number of from fields seen */
- mgt_sncnt, /* number of sender fields seen */
-
- mgt_doloc, /* send "immediate" channels, if any */
- mgt_donet, /* send "network" channels, if any */
- mgt_loops, /* number of times through this site */
- mgt_hops; /* number of hops message has gone */
- /**/
-
- mgt_init ()
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_init ()");
- #endif
- if (ch_dflnam[0] != '\0')
- if ((mgt_chdfl = ch_nm2struct (ch_dflnam)) == (Chan *) NOTOK)
- err_abrt (RP_PARM, "'%s' invalid default channel name", ch_dflnam);
-
- return (RP_OK);
- }
-
- mgt_minit () /* initialize for new message */
- {
- register Chan **chanptr;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_minit ()");
- #endif
-
- if (mgt_txsrc) /* if previously set */
- free (mgt_txsrc);
- /**/ll_log(logptr, LLOGFTR, "mgt_txsrc freed");
- if (mgt_vchan.mgt_ahost) /* " " " */
- free (mgt_vchan.mgt_ahost);
- /**/ll_log(logptr, LLOGFTR, "mgt_vchan.mgt_ahost freed");
- if (mgt_return)
- free (mgt_return);
- /**/ll_log(logptr, LLOGFTR, "mgt_return freed");
-
- mgt_vchan.mgt_achan = (Chan *) 0;
- /**/ll_log(logptr, LLOGFTR, "mgt_vchan.mgt_achan reset");
- mgt_vchan.mgt_ahost = (char *) 0;
- /**/ll_log(logptr, LLOGFTR, "mgt_vchan.mgt_ahost reset");
- mgt_txsrc = (char *) 0;
- /**/ll_log(logptr, LLOGFTR, "mgt_txsrc reset");
- mgt_return = (char *) 0;
- /**/ll_log(logptr, LLOGFTR, "mgt_return reset");
-
- mgt_trust = NRMFROM;
-
- mgt_remail =
- mgt_rt2sndr =
- mgt_s2return =
- mgt_rtgot =
- mgt_okauthor = FALSE;
- mgt_fmcnt =
- mgt_sncnt =
- mgt_gotid =
- mgt_loops =
- mgt_hops = 0;
-
- for (chanptr = ch_tbsrch; *chanptr != 0; chanptr++)
- (*chanptr) -> ch_access &= ~DLVRDID;
- /* reset "used" bit, for channel */
- /**/ll_log(logptr, LLOGBTR, "leaving mgt_init()");
- return (RP_OK);
- }
- /**/
-
- char *
- mgt_parm (theparm)
- register char *theparm;
- {
- char *ptr;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_parm (%s)",theparm);
- #endif
- switch (*theparm)
- {
- case '-':
- break;
-
- case 'h': /* hostname for relay source */
- theparm = prm_dupval (++theparm, &mgt_vchan.mgt_ahost);
- break; /* just save the info, for now */
-
- case 'i': /* relaying Indirectly */
- theparm = prm_dupval (++theparm, &ptr);
- mgt_forward (ptr);
- free (ptr);
- break; /* certify legality of relaying */
-
- case 'l': /* send local now, if have any */
- mgt_doloc = TRUE;
- break;
-
- case 'n': /* send net now, if have any */
- mgt_donet = TRUE;
- break;
-
- case 'r': /* get RETURN from login info */
- mgt_rt2sndr = TRUE; /* and not explicit specification */
- break;
-
- case 's': /* get RETURN from Sender info */
- mgt_s2return = TRUE;
- break;
-
- case 't': /* TRUST me; don't authenticate */
- mgt_trust = OKFROM;
- break;
-
- case 'u': /* (close to 't'); no authentication */
- mgt_trust = FLGFROM;
- break;
-
- case 'd': /* don't use delay channel */
- mgt_nodelay = TRUE;
- break;
-
- case 'j': /* I really am the delay channel */
- mgt_amdelay = TRUE;
- mgt_nodelay = TRUE;
- break;
-
- case 'k':
- theparm = prm_dupval (++theparm, &ptr);
- #ifdef NAMESERVER
- ns_settimeo(atoi(ptr));
- #endif
- free(ptr);
- break;
-
- default:
- return ((char *) NOTOK); /* not a management parameter */
- }
-
- return (theparm);
- }
- /**/
-
- mgt_pend () /* end of parameters */
- {
- AP_ptr rtntree;
- AP_ptr local, domain, route;
- char rtnbuf[ADDRSIZE];
- register short len;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_pend ()");
- #endif
-
- mgt_source();
-
- if (mgt_rt2sndr) /* Use sender for return address */
- {
- mgt_return = multcat(mailid, "@", locfullname, (char *)0);
- mgt_rtgot = TRUE;
- }
- else { /* submittor specifying return */
- if (!mgt_s2return) /* take msg directly */
- {
- register char *cp;
-
- if ((len = ut_stdin (rtnbuf, LINESIZE, nlnultrm, NOTOK)) <= 0)
- err_abrt (RP_LIO, "error copying return address");
-
- /* Suck up leading white space */
- for (cp = rtnbuf; isspace(*cp); cp++);
-
- if (*cp == '\n')
- *cp = '\0';
- if (*cp == '\0')
- /* Special Case: Null return address --> Quiet flag */
- dlv_flgs |= ADR_NORET;
- else if (len > (sizeof(rtnbuf) - 1))
- err_msg (RP_LIO, "return address too long");
- else if ((rtntree = ap_s2tree (cp)) == (AP_ptr) NOTOK)
- err_msg (RP_PARM, "Problem with return address '%s'", rtnbuf);
- else {
- rtntree = ap_normalize (mgt_vchan.mgt_ahost, (char *) 0,
- rtntree, (Chan *)0);
- if(rtntree == (AP_ptr)MAYBE)
- err_msg (RP_NS, "Nameserver timeout for '%s'", rtnbuf);
- ap_t2parts(rtntree, (AP_ptr *)0, (AP_ptr *)0, &local,
- &domain, &route);
- mgt_return = ap_p2s( (AP_ptr) 0, (AP_ptr) 0, local, domain,
- route);
- ap_sqdelete (rtntree, (AP_ptr) 0);
- ap_free (rtntree); /* delete full string */
- if(mgt_return == (char *)MAYBE)
- err_msg (RP_NS, "Nameserver timeout for '%s'", rtnbuf);
- mgt_rtgot = TRUE;
- }
- }
- }
-
- if (mgt_vchan.mgt_achan == (Chan *) 0)
- auth_init (username, (mgt_trust == NRMFROM));
- else
- auth_init ((mgt_return ? mgt_return : ""), (mgt_trust == NRMFROM));
-
- if(pro_vfadr)
- pro_reply (RP_OK, "Sender is '%s'", mgt_return ? mgt_return : "");
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "mgt_return: '%s'", mgt_return ? mgt_return : "");
- #endif
- }
- /**/
-
- #define AOKNUM 50
-
- mgt_aok (thechan, hostr, mbox, parm) /* is address acceptable for sending */
- Chan *thechan; /* internal chan name/code */
- char *hostr, /* official name of host */
- *mbox, /* name of mailbox */
- *parm; /* local-mailbox parameter */
- {
- register struct passwd *pwdptr;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_aok (%s, %s, %s, %s)", thechan->ch_name,
- hostr, mbox, parm);
- #endif
-
- /* if address maps to file or process, login uid must meet the following
- * restrictions.
- */
-
- if (thechan == mgt_chdfl) /* "local" address */
- {
- switch (parm[0])
- {
- case '/': /* file destination */
- case '|': /* process destination */
- if ((pwdptr = getpwmid (mbox)) == (struct passwd *) NULL)
- {
- ll_err (logptr, LLOGTMP,
- "user '%s' not in passwd file", mbox);
- return (FALSE); /* can't deliver to non-persons */
- }
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "caller uid (%d), parm uid (%d)",
- adruid, pwdptr -> pw_uid);
- #endif
- if (!mgt_inalias)
- /* only accept from alias file */
- /* unless 'insecure' */
- #ifdef INSECURE
- /*
- * Only do this code if you are willing to take the
- * implied security risk. I do not trust this (DPK).
- *
- * Must be ((your own login id or privelidged user)
- * and locally originated) (SEK - note de Morgan!!)
- */
- if (((adruid != pwdptr -> pw_uid) && (adruid != 0)) ||
- (mgt_vchan.mgt_achan != (Chan *) 0))
- #endif
- return (FALSE);
- }
- }
-
- /* is this address subject to immediate transmission, if requested?
- * the check, here, is more for convenience than for enforcement,
- * since Deliver will have to redo the check. this is just to
- * avoid calling Deliver unnecessarily.
- */
-
- if (! (thechan -> ch_access & (DLVRPSV | DLVRBAK)))
- { /* an active, foreground-able chan? */
- if ((thechan -> ch_access & DLVRIMM) || mgt_donet)
- thechan -> ch_access |= DLVRDID; /* channel may be run now */
- }
-
- if (mgt_vchan.mgt_achan == (Chan *) 0)
- return (auth_user (mgt_chdfl -> ch_lname, hostr,
- mgt_chdfl, thechan));
- else
- return (auth_user (mgt_vchan.mgt_ahost, hostr,
- mgt_vchan.mgt_achan, thechan));
- /* apply control policies relating to */
- /* channel access */
- }
-
- mgt_aend ()
- { /* record some stats */
- char sizstr[11];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_aend ()");
- #endif
-
- if (lnk_nadrs <= 0)
- err_msg (RP_NDEL, "No valid addresses");
-
- sprintf (sizstr, "%ld", tx_msize);
- /* ll_log can't handle longs */
- if (mgt_vchan.mgt_achan == 0) /* local submission */
- ll_log (logptr, LLOGBST, "lin %s (%d, %s) %s %s",
- mq_munique, lnk_nadrs, sizstr, mgt_chdfl->ch_queue, mailid);
- else
- { /* claiming to be a relay */
- if (!mgt_s2return && /* hack past possible bad parsing */
- mgt_return != NULL && !isnull (*mgt_return) &&
- !index(mgt_return, '@'))/* add host if necessary if not given */
- {
- char *cp;
-
- cp = multcat(mgt_return, "@", mgt_vchan.mgt_ahost, (char *)0);
- free (mgt_return);
- mgt_return = cp;
- }
-
- ll_log (logptr, LLOGBST, "rin %s (%d, %s) %s %s %s",
- mq_munique, lnk_nadrs, sizstr,
- mgt_vchan.mgt_achan -> ch_queue, mgt_vchan.mgt_ahost,
- mgt_return);
-
- }
- auth_end ();
- return (RP_OK);
- }
-
- /**/
-
- mgt_source () /* ready to process headers */
- {
- char linebuf[LINESIZE];
-
- if (mgt_vchan.mgt_achan != 0)
- {
- if (mgt_vchan.mgt_ahost == 0)
- { /* no source host named */
- if (mgt_vchan.mgt_achan -> ch_host == NORELAY)
- { /* not a single relay for the chan */
- if(mgt_amdelay && PRIV_USER(userid))
- mgt_vchan.mgt_ahost = strdup(adr_fulldmn);
- else /* cheat here should do an err_abrt with RP_NS ?? */
- if (tb_k2val (mgt_vchan.mgt_achan -> ch_table, TRUE,
- username, linebuf) != OK)
- /* derive it from login name */
- err_abrt(RP_PARM,"'%s' not an authorized %s (%s) relay",
- username,
- mgt_vchan.mgt_achan -> ch_table -> tb_name,
- mgt_vchan.mgt_achan -> ch_name);
- else
- mgt_vchan.mgt_ahost = strdup (linebuf);
- }
- else /* take name from ch_tai structure */
- mgt_vchan.mgt_ahost = strdup (mgt_vchan.mgt_achan -> ch_host);
- }
- else if (!PRIV_USER(userid)) /* trying to name host explicitly */
- err_abrt (RP_PARM,
- "only root, mmdf and daemons may name source host");
- }
- }
-
- mgt_hinit () /* ready to process headers */
- {
- if (mgt_vchan.mgt_achan != 0)
- mgt_via();
- }
-
- /*
- * Authentication of "Resent" messages is quit a bit looser than
- * authentication of original messages. This is due to the fact
- * that a message might be resent several times, each time gaining
- * a new set of Resent- headers. The last set wins. (DPK, 17 July 84)
- */
- mgt_hdr (name, contents, hdr_state)
- char *name,
- contents[];
- int hdr_state;
- {
- int ind,
- argc;
- char *argv[25];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_hdr ()");
- #endif
-
- if (prefix ("Resent-", name))
- {
- name += 7;
- goto doremail;
- }
- if (prefix ("Remailed-", name))
- {
- name += 9;
- goto doremail;
- }
- if (prefix ("Redistributed-", name))
- {
- name += 14;
- doremail:
- if (!mgt_remail)
- {
- mgt_sncnt = mgt_fmcnt = 0;
- mgt_remail = TRUE;
- }
- if (lexequ ("Sender", name))
- goto dosn;
- if (lexequ ("From", name))
- goto dofm;
- if (lexequ ("Reply-to", name))
- goto dorplyto;
- }
-
- if (lexequ ("Sender", name))
- {
- if (!mgt_remail)
- {
- dosn:
- mgt_sncnt++;
- if (mgt_trust == NRMFROM)
- mgt_okauthor = mgt_author (contents);
-
- if (mgt_s2return) { /* use Sender field for return addr */
- compress (contents, contents);
- mgt_return = strdup(contents);
- mgt_rtgot = TRUE;
- }
-
- }
- }
- else
- if (lexequ ("From", name))
- {
- if (!mgt_remail)
- {
- dofm:
- mgt_fmcnt++;
-
- /* Sender overrides; contents of From */
- if (mgt_trust == NRMFROM)
- if (mgt_remail || mgt_sncnt == 0)
- mgt_okauthor = mgt_author (contents);
-
- if (mgt_s2return && !mgt_rt2sndr && !mgt_rtgot) {
- compress (contents, contents);
- mgt_return = strdup(contents);
- } /* get return from From, if no Sender */
- }
- }
- else
- if (lexequ ("Reply-To", name))
- {
- if (!mgt_remail)
- {
- dorplyto:
- if (!mgt_s2return && !mgt_rt2sndr && !mgt_rtgot)
- {
- compress (contents, contents);
- mgt_return = strdup(contents);;
- mgt_rtgot = TRUE; /* From doesn't set it, but Reply-to does */
- }
- }
- }
- else
- if (lexequ ("Via", name)) /* old rfc733 pseudo-standard */
- {
- /*
- * Only inc mgt_hops if this is the first line of the trace
- */
- if (hdr_state != HDR_MOR && ++mgt_hops > maxhops)
- {
- if (mgt_vchan.mgt_achan != (Chan *) 0)
- ll_log (logptr, LLOGTMP, "reject on hop count from: %s %s %s",
- mgt_vchan.mgt_achan -> ch_name, mgt_vchan.mgt_ahost,
- mgt_return);
- else
- ll_log (logptr, LLOGTMP, "reject last hop: %s", contents);
- err_msg (RP_NDEL, "Message has travelled too many hops");
- }
-
- argc = str2arg (contents, 25, argv, (char *) 0);
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "from '%s'; contents '%s'",
- mgt_vchan.mgt_ahost, argv[0]);
- #endif
-
- if (mgt_vchan.mgt_achan != (Chan *) 0 &&
- lexequ (mgt_vchan.mgt_ahost, argv[0]) &&
- ++mgt_loops > 2)
- {
- ll_log (logptr, LLOGTMP, "reject on loop from: %s %s %s",
- mgt_vchan.mgt_achan -> ch_name, mgt_vchan.mgt_ahost,
- mgt_return);
- err_msg (RP_NDEL,
- "Message has been through this site (%s) already",
- locfullname);
- }
- }
- if (lexequ ("Received", name)) /* RFC822 standard */
- {
- /*
- * Only inc mgt_hops if this is the first line of the trace
- */
- if (hdr_state != HDR_MOR && ++mgt_hops > maxhops)
- {
- if (mgt_vchan.mgt_achan != (Chan *) 0)
- ll_log (logptr, LLOGTMP, "reject on hop count from: %s %s %s",
- mgt_vchan.mgt_achan -> ch_name, mgt_vchan.mgt_ahost,
- mgt_return);
- else
- ll_log (logptr, LLOGTMP, "reject last hop: %s", contents);
- err_msg (RP_NDEL, "Message has travelled too many hops");
- }
-
- argc = str2arg (contents, 25, argv, (char *) 0);
- for (ind = 0; ind < argc - 2; ind += 2)
- if (lexequ (argv[ind], "by"))
- break; /* found the field naming the receiver */
-
- if (ind++ < argc)
- { /* compare our name with 'received' name */
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "from '%s'; contents '%s'",
- mgt_vchan.mgt_ahost, argv[ind]);
- #endif
-
- if (mgt_vchan.mgt_achan != (Chan *) 0 &&
- lexequ (mgt_vchan.mgt_achan -> ch_lname, argv[ind]) &&
- ++mgt_loops > 2)
- {
- ll_log (logptr, LLOGTMP, "reject on loop from: %s %s %s",
- mgt_vchan.mgt_achan -> ch_name,
- mgt_vchan.mgt_achan -> ch_lname,
- mgt_return);
- err_msg (RP_NDEL,
- "Message has been through this site (%s) too many times",
- mgt_vchan.mgt_achan -> ch_lname);
- }
- }
- }
- if (lexequ ("Message-Id", name))
- {
- mgt_gotid++;
- }
- return (RP_OK); /* no management policies, for this one */
- }
- /**/
-
- mgt_hend ()
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_hend ()");
- ll_log (logptr, LLOGFTR, "uid=%d,effec=%d, fmcnt=%d,okauth=%d",
- userid, effecid, mgt_fmcnt, mgt_okauthor);
- #endif
-
- if (!mgt_remail) {
- if (mgt_sncnt == 0 && mgt_fmcnt > 1 && mgt_trust == NRMFROM)
- err_msg (RP_PARM, "Too many From: lines");
- if (mgt_sncnt > 1 && mgt_trust == NRMFROM)
- err_msg (RP_PARM, "Too many Sender: lines");
- }
-
- if (mgt_trust == OKFROM) /* pure trust requested */
- {
- if (!PRIV_USER(userid) && mgt_vchan.mgt_achan == 0)
- /* trust root, mmdf, and relays */
- mgt_trust = FLGFROM; /* otherwise note, but honor */
- }
-
- if (mgt_addid && !mgt_gotid)
- mgt_messageid ();
-
- if (mgt_trust == FLGFROM || mgt_txsrc != 0)
- mgt_srcinfo (); /* this must follow the above "if" */
-
- if (mgt_trust != NRMFROM)
- return (RP_OK); /* not checking for these errors */
-
- if (!mgt_okauthor)
- err_msg (RP_PARM, "No valid author specification present");
-
- return (RP_OK);
- }
- /**/
-
- LOCFUN
- mgt_forward (channame) /* certify source as relay site */
- char channame[];
- { /* map username to "host" on chan */
- register Chan *thechan; /* chan claiming to come from */
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_forward (%s)", channame);
- #endif
-
- if ((thechan = ch_nm2struct (channame)) == (Chan *) NOTOK)
- err_abrt (RP_PARM, "Channel '%s' does not exist", channame);
-
- mgt_vchan.mgt_achan = thechan;
- }
-
- /**/
-
- LOCFUN
- mgt_author (contents) /* does component contain only the */
- char contents[];
- { /* address of the actual sender? */
- struct passwd *pwdptr;
- AP_ptr locptr, /* local & domain parts */
- dmnptr,
- aptr;
- int retval = TRUE;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_author(%s)", contents);
- #endif
-
- /* do not normalize. evaluate as is */
- if ((aptr = ap_s2tree (contents)) == (AP_ptr) NOTOK
- || ap_t2parts (aptr, (AP_ptr *) 0, (AP_ptr *) 0,
- &locptr, &dmnptr, (AP_ptr *) 0) != (AP_ptr) OK) {
- retval = FALSE; /* only allowed one address in the field */
- goto cleanup;
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "checking: %s, uid %d, %s", locptr -> ap_obvalue,
- userid, dmnptr ? dmnptr -> ap_obvalue : "No Domain");
- #endif
- if ((pwdptr = getpwmid (locptr -> ap_obvalue)) == (struct passwd *)NULL
- || pwdptr -> pw_uid != userid)
- retval = FALSE;
- /*
- * If a domain was specified, make sure it was the proper one.
- */
- if (retval == TRUE && dmnptr != (AP_ptr) 0) {
- Dmn_route dmnroute;
- char tmpbuf[LINESIZE];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_author, v2route(%s)",dmnptr->ap_obvalue);
- #endif
- switch ((int)dm_v2route (dmnptr -> ap_obvalue, tmpbuf, &dmnroute)) {
- case MAYBE:
- retval = FALSE;
- break;
- case OK: /* Can't happen ?? -DPK- */
- retval = TRUE;
- break;
- default:
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_author, h2chan(%s)", dmnroute.dm_argv[0]);
- #endif
- if (ch_h2chan (dmnroute.dm_argv[0], 1) != OK)
- retval = FALSE;
- break;
- case NOTOK:
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_author, h2chan(%s)", dmnptr->ap_obvalue);
- #endif
- if (ch_h2chan (dmnptr -> ap_obvalue, 1) != OK)
- retval = FALSE;
- break;
- }
- }
-
- cleanup:
- if (aptr && aptr != (AP_ptr)NOTOK) {
- ap_sqdelete (aptr, (AP_ptr) 0);
- ap_free (aptr);
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_author, returns %d", retval);
- #endif
- return (retval);
- }
- /**/
-
- LOCFUN
- mgt_messageid () /* add Message-ID: */
- {
- char buf[32];
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_messageid ()");
- #endif
-
- if (isstr(locfullmachine))
- fprintf(mq_mffp, "Message-ID: <%s.%s@%s>\n",
- cnvtdate(TIMCOM, buf), &mq_munique[4], locfullmachine);
- else
- fprintf(mq_mffp, "Message-ID: <%s.%s@%s>\n",
- cnvtdate(TIMCOM, buf), &mq_munique[4], locfullname);
- }
-
- LOCFUN
- mgt_srcinfo () /* add Source-Info field, maybe */
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_srcinfo ()");
- #endif
-
- fputs ("Source-Info: ", mq_mffp);
- if (mgt_trust == FLGFROM)
- { /* note the lack of authentication */
- fputs ("From (or Sender) name not authenticated.\n", mq_mffp);
- if (mgt_txsrc != 0) /* indent second line of text */
- fputs (" ", mq_mffp);
- }
- if (mgt_txsrc != 0) /* user wants to say something */
- {
- fputs (mgt_txsrc, mq_mffp);
- if (mgt_txsrc[strlen (mgt_txsrc) - 1] != '\n')
- putc ('\n', mq_mffp);
- }
- }
-
- /**/
-
- LOCFUN
- mgt_via () /* note fact of relaying */
- {
- extern char *cnvtdate ();
- char thedate[LINESIZE];
- int len;
- #ifdef VIATRACE
- char *p;
- #endif
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "mgt_via ()");
- #endif
-
- /* Received: by hostname.net; date */
- /* e.g.: */
- /* Received: by Rand-Unix.ArpaNet; 21 Jan 79 12:40 EDT */
-
- if (mgt_vchan.mgt_achan -> ch_login != NOLOGIN)
- /* single login authorized to relay */
- if (!PRIV_USER(userid)) /* caller is not special id */
- if (!lexequ (mgt_vchan.mgt_achan -> ch_login, username))
- /* caller not the authorized id */
- err_abrt (RP_USER, "%s not authorized to submit mail as %s",
- username, mgt_vchan.mgt_achan -> ch_name);
-
- cnvtdate (TIMSHRT, thedate); /* net name & short date/time */
-
- /* if mail always goes through a relay, for this channel, then the
- * host/chan combination is a constant and source reference is not
- * useful; only the receiver will be listed. The channel name is
- * used to specify the transfer link.
- */
-
- #ifdef VIATRACE
- /* needed for standard UK sites */
- /* note reversed domain ordering*/
- len = mgt_rcv (0, "Via:");
- if (mgt_vchan.mgt_achan -> ch_host == NORELAY)
- p = ap_dmflip (mgt_vchan.mgt_ahost);
- else
- p = ap_dmflip (mgt_vchan.mgt_achan -> ch_host);
- len = mgt_rcv (len, " %s;", p);
- free (p);
- #else /* VIATRACE */
-
- len = mgt_rcv (0, "Received:");
-
- if(mgt_amdelay != TRUE){ /* special string for Delay channel */
- if (mgt_vchan.mgt_achan -> ch_host == NORELAY)
- len = mgt_rcv (len, "from %s", mgt_vchan.mgt_ahost);
- else
- len = mgt_rcv (len, "from %s", mgt_vchan.mgt_achan -> ch_host);
- }
-
- #ifndef UCL
- /* We must have a seperate "locmachine" here since the name we
- * want to record is dependant on the channel.
- * What confuses me is why doesn't the UCL portion have the domain
- * flipped around? And also, why don't they make it relative to
- * the channel? And another thing, why doesn't the non-UCL portion
- * put the "show" information in the header?
- * -- DSH
- */
- if (isstr (locmachine))
- len = mgt_rcv (len, "by %s.%s.%s", locmachine,
- mgt_vchan.mgt_achan -> ch_lname,
- mgt_vchan.mgt_achan -> ch_ldomain);
- else
- len = mgt_rcv (len, "by %s.%s",
- mgt_vchan.mgt_achan -> ch_lname,
- mgt_vchan.mgt_achan -> ch_ldomain);
- if (adr_orgspec != (char *) 0)
- len = mgt_rcv (len, "for %s", adr_orgspec);
- len = mgt_rcv (len, "id %s;", &mq_munique[4]);
- /* skip the "msg." preface */
- #else /* UCL */
- if (isstr (locmachine))
- len = mgt_rcv (len, "by %s.%s.%s ", locmachine, locname, locdomain);
- else
- len = mgt_rcv (len, "by %s.%s ", locname, locdomain);
- /* SEK use local rather than channel pref names? */
- /* structure ch_show to suit tase */
- if(mgt_amdelay == TRUE)
- len = mgt_rcv (len, " with Delay channel");
- else
- len = mgt_rcv (len, " %s", mgt_vchan.mgt_achan -> ch_show);
- len = mgt_rcv (len, " id %s;", &mq_munique[4]);
- /* skip the "msg." preface */
- #endif /* UCL */
-
- #endif /* VIATRACE */
- (void) mgt_rcv (len, "%s\n", thedate);
- }
-
- /* VARARGS2 */
-
- LOCVAR
- mgt_rcv (curlen, fmt, val1, val2, val3)
- int curlen;
- char *fmt, *val1, *val2, *val3;
- {
- char linebuf[LINESIZE];
- int len;
-
- sprintf (linebuf, fmt, val1, val2, val3);
- len = strlen (linebuf);
- if ((curlen + len) > 77)
- {
- fputs ("\n ", mq_mffp);
- curlen = 10;
- }
- else
- if (curlen > 0)
- putc (' ', mq_mffp);
- fputs (linebuf, mq_mffp);
- return (curlen + len);
- }
-
- /* generate a delay channel 'host parameter' */
-
- char *
- mgt_dstgen()
- {
- char *multcat();
- return(multcat(mgt_vchan.mgt_achan == NULL ?
- mgt_dlname : mgt_vchan.mgt_achan->ch_name,
- "&", mgt_vchan.mgt_ahost, (char *)0));
- }
-